﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace Douya.Json
{
    public class JsonObject : IJsonValue
    {
        Dictionary<String, IJsonValue> map;

        public JsonObject(Dictionary<String, IJsonValue> map)
        {
            this.map = map;
        }

        //--------------------------------------------------------------------------------------------------------------
        // IJsonValue

        public ValueType Type
        {
            get { return ValueType.TypeObject; }
        }

        public bool GetBoolean()
        {
            return map.Count > 0;
        }

        public int GetInteger()
        {
            return map.Count;
        }

        public string GetString()
        {
            return "object";
        }

        public JsonObject GetObject()
        {
            return this;
        }

        public JsonArray GetArray()
        {
            return null;
        }

        //--------------------------------------------------------------------------------------------------------------
        // JsonObject

        public int Count
        {
            get { return map.Count; }
        }

        public Dictionary<String, IJsonValue>.KeyCollection Keys {
            get { return map.Keys; }
        }

        public bool Contain(string name)
        {
            return map.ContainsKey(name);
        }

        public IJsonValue GetValue(string name)
        {
            if (!map.ContainsKey(name))
            {
                return null;
            }
            return map[name];
        }

        public bool GetBoolean(string name)
        {
            if (!map.ContainsKey(name))
            {
                return false;
            }
            return map[name].GetBoolean();
        }

        public int GetInteger(string name)
        {
            return map[name].GetInteger();
        }

        public int GetInteger(string key, int def)
        {
            if (!map.ContainsKey(key))
            {
                return def;
            }
            return map[key].GetInteger();
        }

        public string GetString(string name)
        {
            if (!map.ContainsKey(name))
            {
                return null;
            }
            return map[name].GetString();
        }

        public string GetString(string key, string def)
        {
            if (!map.ContainsKey(key))
            {
                return def;
            }
            return map[key].GetString();
        }

        public JsonObject GetObject(string name)
        {
            string[] list = name.Split('.');
            if (list.Length > 1)
            {
                return GetObject(this, list);
            }
            if (!map.ContainsKey(name))
            {
                return null;
            }
            return map[name].GetObject();
        }

        JsonObject GetObject(JsonObject parent, string[] list)
        {
            IJsonValue result = parent;
            for (int i = 0; i < list.Length && result != null; ++i)
            {
                if (i + 1 > list.Length - 1)
                {
                    string name = list[i];
                    if (Char.IsDigit(name.ToCharArray()[0]))
                    {
                        result = (result as JsonArray).GetValue(int.Parse(name));
                    }
                    else
                    {
                        result = (result as JsonObject).GetValue(name);
                    }
                    break;
                }
                else
                {
                    string name = list[i];
                    if (Char.IsDigit(name.ToCharArray()[0]))
                    {
                        result = (result as JsonArray).GetValue(int.Parse(name));
                    }
                    else
                    {
                        result = (result as JsonObject).GetValue(name);
                    }
                }
            }
            return result as JsonObject;
        }

        public JsonArray GetArray(string name)
        {
            if (!map.ContainsKey(name))
            {
                return null;
            }
            return map[name].GetArray();
        }

        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("{");
            foreach (String name in map.Keys)
            {
                builder.AppendFormat("\"{0}\":{1},", name, map[name].ToString());
            }
            if (builder.Length > 1)
            {
                --builder.Length;
            }
            builder.Append("}");
            return builder.ToString();
        }
    }
}
